<!--

    Licensed to the Apache Software Foundation (ASF) under one or more
    contributor license agreements.  See the NOTICE file distributed with
    this work for additional information regarding copyright ownership.
    The ASF licenses this file to You under the Apache License, Version 2.0
    (the "License"); you may not use this file except in compliance with
    the License.  You may obtain a copy of the License at

       https://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.

-->

<template>
  <div>
    <a-card
      style="margin-top: 24px"
      :bordered="false">
      <div slot="extra">
        <a-radio-group
          button-style="solid"
          default-value="">
          <a-radio-button
            @click="handleQuery()"
            value="">
            All
          </a-radio-button>
          <a-radio-button
            @click="handleQuery(-1)"
            value="-1">
            Not Build
          </a-radio-button>
          <a-radio-button
            @click="handleQuery(0)"
            value="0">
            Building
          </a-radio-button>
          <a-radio-button
            @click="handleQuery(1)"
            value="1">
            Build Success
          </a-radio-button>
          <a-radio-button
            @click="handleQuery(2)"
            value="2">
            Build Failed
          </a-radio-button>
        </a-radio-group>
        <a-input-search
          @search="handleSearch"
          style="margin-left: 16px; width: 272px;" />
      </div>

      <div
        class="operate"
        v-permit="'project:create'">
        <a-button
          type="dashed"
          style="width: 100%"
          icon="plus"
          @click="handleAdd">
          Add New
        </a-button>
      </div>

      <a-list
        size="large"
        :pagination="pagination">
        <a-list-item
          :key="index"
          v-for="(item, index) in dataSource">
          <a-list-item-meta>
            <a-badge class="build-badge" v-if="item.buildState === -2" slot="avatar" count="NEW" title="this project has changed,need rebuild">
              <svg-icon class="avatar" v-if="item.type === 1" name="flink" size="large"></svg-icon>
              <svg-icon class="avatar" v-if="item.type === 2" name="spark" size="large"></svg-icon>
            </a-badge>
            <template v-else>
              <svg-icon class="avatar" v-if="item.type === 1" name="flink" size="large" slot="avatar"></svg-icon>
              <svg-icon class="avatar" v-if="item.type === 2" name="spark" size="large" slot="avatar"></svg-icon>
            </template>
            <a slot="title">
              {{ item.name }}
              <a-badge
                status="processing"
                title="installing"
                v-if="item.buildState === 0" />
            </a>
            <a-popover
              arrow-point-at-center
              trigger="hover"
              slot="description">
              <template slot="content">
                {{ item.url }}
              </template>
              <a-button
                style="border:unset;height:20px;background:unset;margin-left:0;padding-left:0px;">
                <ellipsis
                  :length="controller.ellipsis">
                  {{ item.description }}
                </ellipsis>
              </a-button>
            </a-popover>
          </a-list-item-meta>

          <div class="list-content">
            <div
              class="list-content-item">
              <span>CVS</span>
              <p>
                <a-icon
                  type="github"
                  two-tone-color />
              </p>
            </div>

            <div class="list-content-item">
              <span>Branches</span>
              <p>
                <a-tag
                  color="blue">
                  {{ item.branches }}
                </a-tag>
              </p>
            </div>
            <div
              class="list-content-item"
              style="width: 180px">
              <span>Last Build</span>
              <p v-if="item.lastBuild">
                {{ item.lastBuild }}
              </p>
              <p v-else>
                --
              </p>
            </div>
            <div
              class="list-content-item"
              style="width: 150px">
              <span>Build State</span>
              <p v-if="item.buildState === -1">
                <a-tag color="#C0C0C0">NOT BUILD</a-tag>
              </p>
              <p v-if="item.buildState === -2">
                <a-tag color="#FFA500">NEED REBUILD</a-tag>
              </p>
              <p v-else-if="item.buildState === 0">
                <a-tag color="#1AB58E" class="status-processing-building">BUILDING</a-tag>
              </p>
              <p v-else-if="item.buildState === 1">
                <a-tag color="#52c41a">SUCCESSFUL</a-tag>
              </p>
              <p v-else>
                <a-tag color="#f5222d">FAILED</a-tag>
              </p>
            </div>
          </div>

          <div class="operation">

            <a-tooltip title="See Build log">
              <a-button
                shape="circle"
                size="small"
                style="margin-left: 8px"
                @click.native="handleSeeLog(item)"
                class="control-button ctl-btn-color">
                <a-icon type="eye"/>
              </a-button>
            </a-tooltip>

            <a-tooltip
              title="Build Project"
              v-if="item.buildState !== 0"
              v-permit="'project:build'">
              <a-popconfirm
                title="Are you sure build this project?"
                cancel-text="No"
                ok-text="Yes"
                @confirm="handleBuild(item)">
                <a-button
                  shape="circle"
                  size="small"
                  style="margin-left: 8px"
                  class="control-button ctl-btn-color">
                  <a-icon type="thunderbolt" />
                </a-button>
              </a-popconfirm>
            </a-tooltip>

            <a-tooltip title="Update Project">
              <a-button
                v-permit="'project:update'"
                @click.native="handleEdit(item)"
                shape="circle"
                size="small"
                style="margin-left: 8px"
                class="control-button ctl-btn-color">
                <a-icon type="edit"/>
              </a-button>
            </a-tooltip>

            <a-tooltip title="Delete Project">
              <a-popconfirm
                title="Are you sure delete this project ?"
                cancel-text="No"
                ok-text="Yes"
                @confirm="handleDelete(item)">
                <a-button
                  type="danger"
                  shape="circle"
                  size="small"
                  style="margin-left: 8px"
                  class="control-button">
                  <a-icon type="delete"/>
                </a-button>
              </a-popconfirm>
            </a-tooltip>

          </div>

        </a-list-item>
      </a-list>
    </a-card>

    <a-modal
      v-model="controller.visible"
      width="65%"
      :body-style="controller.modalStyle"
      :destroy-on-close="controller.modalDestroyOnClose"
      :footer="null">
      <template slot="title">
        <a-icon type="file-text" />&nbsp;
        {{ controller.consoleName }}
      </template>
      <div
        id="terminal"
        ref="terminal"
        class="terminal" />
    </a-modal>
  </div>
</template>
<script>
import { build, buildlog, list,remove } from '@api/project'
import Ellipsis from '@comp/Ellipsis'
import {mapActions} from 'vuex'
import { Terminal } from 'xterm'
import 'xterm/css/xterm.css'

import SvgIcon from '@/components/SvgIcon'

export default {
  components: { Ellipsis, SvgIcon },
  data () {
    return {
      loading: false,
      advanced: false,
      dataSource: [],
      queryParams: {},
      sortedInfo: null,
      stompClient: null,
      terminal: null,
      projectId: null,
      controller: {
        ellipsis: 100,
        modalStyle: {
          height: '600px',
          padding: '5px'
        },
        visible: false,
        modalDestroyOnClose: true,
        consoleName: null
      },
      pagination: {
        pageSizeOptions: ['10', '20', '30', '40', '100'],
        defaultCurrent: 1,
        defaultPageSize: 10,
        showQuickJumper: true,
        showSizeChanger: true,
        onChange:(page,pageSize)=>{
          this.queryParams.pageNum = page
          this.handleFetch(this.queryParams, false)
        },
        onShowSizeChange:(current,size)=>{
          this.queryParams.pageNum = 1
          this.queryParams.pageSize = size
          this.handleFetch(this.queryParams, false)
        },
        showTotal: (total, range) => `display ${range[0]} ~ ${range[1]} record，total ${total} `
      }
    }
  },

  mounted () {
    this.handleFetch(this.queryParams, true)
    const timer = window.setInterval(() => this.handleFetch(this.queryParams, false), 2000)
    this.$once('hook:beforeDestroy', () => {
      clearInterval(timer)
    })
  },

  methods: {
    ...mapActions(['SetProjectId']),

    handleSearch (value) {
      this.paginationInfo = null
      this.queryParams.name = value
      this.handleFetch({
        ...this.queryParams
      }, true)
    },

    handleBuild (record) {
      this.$swal.fire({
        icon: 'success',
        title: 'The current project is building',
        showConfirmButton: false,
        timer: 2000
      }).then((r)=> {
        build({
          id: record.id,
        })
      })
    },

    handleAdd () {
      this.$router.push({ 'path': '/flink/project/add' })
    },

    handleEdit(item) {
      this.SetProjectId(item.id)
      this.$router.push({'path': '/flink/project/edit'})
    },

    handleDelete(item) {
      remove({
        id: item.id
      }).then((resp) => {
        if ( resp.data ) {
          this.$swal.fire({
            icon: 'success',
            title: 'delete successful',
            showConfirmButton: false,
            timer: 2000
          }).then((result) => {
            this.handleFetch(this.queryParams, true)
          })
        } else {
          this.$swal.fire(
            'Failed',
            'Please check if any application belongs to this project',
            'error'
          )
        }
      })
    },

    handleSeeLog (project) {
      this.controller.consoleName = project.name + ' build log'
      this.controller.visible = true
      this.$nextTick(function () {
        this.handleOpenWS(project)
      })
    },

    handleOpenWS (project) {
      this.projectId = project.id
      const rows = parseInt(this.controller.modalStyle.height.replace('px', '')) / 16
      const cols = (document.querySelector('.terminal').offsetWidth - 10) / 8
      this.terminal = new Terminal({
        cursorBlink: true,
        rendererType: 'canvas',
        termName: 'xterm',
        useStyle: true,
        screenKeys: true,
        convertEol: true,
        scrollback: 1000,
        tabstopwidth: 4,
        disableStdin: true,
        rows: parseInt(rows), // Rows
        cols: parseInt(cols),
        fontSize: 14,
        cursorStyle: 'underline', // Cursor style
        theme: {
          foreground: '#AAAAAA', // Font
          background: '#131D32', // background color
          lineHeight: 16
        }
      })
      const container = document.getElementById('terminal')
      this.terminal.open(container, true)
      this.fetchBuildLog(project, null)
    },

    fetchBuildLog(project, startOffset) {
      buildlog({
        id: project.id,
        startOffset: startOffset
      }).then((resp) => {
        this.terminal.write(resp.data)
        if (resp.readFinished === false) {
          window.setTimeout(() => this.fetchBuildLog(project, resp.offset), 500)
        }
      })
    },

    handleQuery (state) {
      this.queryParams.buildState = state
      this.handleFetch({
        ...this.queryParams
      }, true)
    },

    handleFetch (params, loading) {
      if (loading) {
        this.loading = true
      }
      if (this.paginationInfo) {
        // If the paging information is not empty, set the current page of the table, the number of items per page, and set the query paging parameters
        this.$refs.TableInfo.pagination.current = this.paginationInfo.current
        this.$refs.TableInfo.pagination.pageSize = this.paginationInfo.pageSize
        params.pageSize = this.paginationInfo.pageSize
        params.pageNum = this.paginationInfo.current
      } else {
        // If pagination information is empty, set to default
        // params.pageSize = this.pagination.defaultPageSize
        // params.pageNum = this.pagination.current
      }
      list(params).then((resp) => {
        const pagination = { ...this.pagination }
        pagination.total = parseInt(resp.data.total)
        this.dataSource = resp.data.records
        this.pagination = pagination
        this.loading = false
      })
    }
  }
}
</script>

<style lang="less" scoped>
.ant-avatar-lg {
  width: 48px;
  height: 48px;
  line-height: 48px;
}

.list-content-item {
  display: inline-block;
  vertical-align: middle;
  font-size: 14px;
  margin-left: 60px;

  span {
    line-height: 20px;
  }

  p {
    margin-top: 4px;
    margin-bottom: 0;
    line-height: 22px;
  }
}

.gutter-box {
  padding: 10px 20px;
  color: rgba(0, 0, 0, 0.65);
  font-size: 14px;
  font-variant: tabular-nums;
  line-height: 1.5;
  list-style: none;
  -webkit-font-feature-settings: 'tnum';
  font-feature-settings: 'tnum';
  position: relative;
  border-radius: 2px;
  transition: all 0.3s;
}

.operation {
  width: 150px;
}

.ant-tag {
  border-radius: 0;
  font-weight: 700;
  font-size: 12px;
  text-align: center;
  padding: 0 4px;
  margin-right: 0px;
  cursor: default;
}

.avatar {
  border-radius: 50%;
  background-color: #ebebeb;
  border: 6px solid #ebebeb;
}

.status-processing-building {
  animation: building-color 800ms ease-out infinite alternate;
}

@keyframes building-color {
  0% {
    border-color: #1AB58E;
    box-shadow: 0 0 1px #1AB58E, inset 0 0 2px #1AB58E;
  }
  100% {
    border-color: #1AB58E;
    box-shadow: 0 0 10px #1AB58E, inset 0 0 5px #1AB58E;
  }
}

.build-badge {
  font-size : 12px;
  -webkit-transform : scale(0.84,0.84) ;
  *font-size:10px;
}
</style>
